/**
 cv.imread，cv.imshow参数 https://docs.opencv.org/4.5.5/df/d24/tutorial_js_image_display.html 
 resize调整图像大小  https://docs.opencv.org/4.5.5/dd/d52/tutorial_js_geometric_transformations.html
 opencv copyTo使用 及 将一个图片显示在另一个图片上 https://blog.csdn.net/weixin_45525272/article/details/122293098
 opencv 在图片上添加文字 https://blog.csdn.net/qq_41962968/article/details/122870539

 图像add方法 https://docs.opencv.org/4.5.5/dd/d4d/tutorial_js_image_arithmetics.html 


 python len() https://zhuanlan.zhihu.com/p/425368974 
 python and,or https://blog.csdn.net/Echo_Zhang12/article/details/111330901 
 python list https://www.runoob.com/python/python-lists.html 
 python range() https://blog.csdn.net/hou09tian/article/details/122985717 
 Python for i in range https://blog.csdn.net/qq_45937199/article/details/111463106 
Python np.append https://blog.csdn.net/weixin_42216109/article/details/93889047
Python np.array https://blog.csdn.net/sinat_34474705/article/details/74458605
Python image.shape https://blog.csdn.net/huima2017/article/details/104798699

 */
async function openCvReady() {
    let src = "./bag_rune.jpg";
    // let src = "./screenshot1.jpg";
    let img_bg = null;
    let src_num1 = "./nums/num_1.png";
    let img_num1 = null;
    // 加载图片
    await Promise.all([await loadImg(src).then(img => {
        // console.log(img);
        // let canvas = document.getElementById('imgCanvas');
        // let ctx = canvas.getContext('2d', {
        //     willReadFrequently: true,
        // });
        // ctx.drawImage(img, 0, 0);
        img_bg = img;
    }), await loadImg(src_num1).then(img => {
        img_num1 = img;
        // console.log(img);
        // let canvas = document.getElementById('imgCanvas');
        // let ctx = canvas.getContext('2d', {
        //     willReadFrequently: true,
        // });
        // ctx.drawImage(img, 0, 0);
    })]);

    // let arr1 = [];
    // p_range(arr1, 1, 5, 2);
    // console.log(arr1);

    cv['onRuntimeInitialized'] = () => {
        console.log(`cv.onRuntimeInitialized()被调用执行`);

        let img_b_m = cv.imread(img_bg);

        // img_num1.width = img_num1.width / 2;
        // img_num1.height = img_num1.height / 2;

        let img_n1_m = cv.imread(img_num1);

        console.log(img_b_m, img_n1_m);

        let size1 = new cv.Size(img_b_m.cols, img_b_m.rows);
        let size2 = new cv.Size(img_n1_m.cols, img_n1_m.rows);

        console.log(size1, size2);

        // 将数字图片添加到rune图片上
        // let imgROI = img_b_m.roi(new cv.Rect(0, 0, img_n1_m.cols, img_n1_m.rows)); //在画布dispImage中划分ROI区域  return Mat(*this, rect); 
        // let mask1 = cv.imread(img_num1, 0);
        // img_n1_m.copyTo(imgROI, mask1);
        // cv.imshow('imgCanvas', img_b_m);

        // 参数1：， Mat& img，待写字的图片，我们写在img图上
        // 参数2：， const string& text，待写入的字，我们下面写入Hello
        // 参数3：， Point org， 第一个字符左下角坐标，我们设定在图片的Point（50,60）坐标。表示x = 50,y = 60。
        // 参数4：， int fontFace，字体类型，FONT_HERSHEY_SIMPLEX ，FONT_HERSHEY_PLAIN ，FONT_HERSHEY_DUPLEX 等等等。
        // 参数5：， double fontScale，字体大小，我们设置为2号
        // 参数6：， Scalar color，字体颜色，颜色用Scalar（）表示，不懂得去百度。
        // 参数7：， int thickness，字体粗细，我们下面代码使用的是4号
        // 参数8：， int lineType，线型，我们使用默认值8.
        // cv.putText(img_b_m, "12", new cv.Point(16,32), cv.FONT_HERSHEY_SIMPLEX, 1, new cv.Scalar(0, 0, 255, 255), 3, cv.LINE_8);
        cv.putText(img_b_m, "1", new cv.Point(8,32), cv.FONT_HERSHEY_SIMPLEX, 1, new cv.Scalar(0, 0, 255, 255), 3, cv.LINE_8);
        cv.imshow('imgCanvas', img_b_m);





        // showManyImages([img_b_m, img_n1_m]);

        // cv.resize(img_b_m, img_n1_m, size1, 0, 0, cv.INTER_AREA);

        // cols width
        // rows height

        // 使用add方法，两个图像大小要相同


        // let cvs = new cv.Mat();
        // let mask = new cv.Mat();
        // let dtype = -1;
        // cv.add(img_b_m, img_n1_m, cvs, mask, dtype); // 两个图像格式不正确 6703288，两个图像宽高不匹配 6703480
        // cv.imshow('imgCanvas', img_b_m);
        // cv.imshow('imgCanvas', img_n1_m);

        // let res = p_numpy_hstack([img_b_m, img_n1_m]);

        // let dispImg = new cv.Mat(size1, cv.CV_8UC3);// 要展示的图片
        // let imgROI1 = dispImg.roi(new cv.Rect(0, 0, img_b_m.cols, img_b_m.rows)); //在画布dispImage中划分ROI区域  return Mat(*this, rect); 
        // console.log(dispImg);
        // cv.resize(img_b_m, imgROI1, size1);// 将要显示的图片设置为imgROI尺寸

        // let imgROI2 = dispImg.roi(new cv.Rect(0, 0, img_n1_m.cols, img_n1_m.rows)); //在画布dispImage中划分ROI区域  
        // cv.resize(img_b_m, imgROI2, size2);// 将要显示的图片设置为imgROI尺寸

        // cv.imshow('imgCanvas', dispImg);

        // cv.imshow('imgCanvas', cvs);

        // img_b_m.delete();
        // img_n1_m.delete();
        // cvs.delete();
        // mask.delete();
    };
    // cv.imshow('imgCanvas', );
}

/**
 * @function
 * @description 
 * @param {[cv.Mat, cv.Mat]} rep 
 * @return {cv.Mat}
 * @link 未完成 opencv同一窗口显示两张图片 https://blog.csdn.net/m0_63014263/article/details/123691982
 * 
 * @todo 功能没完成
*/
function showManyImages(srcImage) {
    let nImages = srcImage.length;  //准备显示的图像个数
    let nSizewindows;   //准备显示图像的布局
    nSizewindows = new cv.Size(2, 1);

    let nRows = 500; //单个图像的显示行
    let nCols = 500; //单个图像的显示列

    //创建矩阵
    let dstImage = new cv.Mat(nRows, nCols * 2, cv.CV_8UC3);

    //修改图片的大小
    cv.resize(srcImage[0], srcImage[0], new cv.Size(nCols, nRows));
    //将修改后的图片复制到dstImage中
    let rect1 = new cv.Rect(0, 0, nCols, nRows);
    let roi1 = dstImage.roi(rect1);
    // srcImage[0].copyTo(roi1.clone());
    // srcImage[0].copyTo(roi1);
    roi1.copyTo(srcImage[0]);

    //修改图片的大小
    cv.resize(srcImage[1], srcImage[1], new cv.Size(nCols, nRows));
    //将修改后的图片复制到dstImage中
    let rect2 = new cv.Rect(1, 0, nCols, nRows);
    let roi2 = dstImage.roi(rect2);
    srcImage[1].copyTo(roi2.clone());


    // cv.imshow("imgCanvas", roi1);
    cv.imshow("imgCanvas", dstImage);
    // cv.imshow("imgCanvas", srcImage[0]);
    // cv.imshow("imgCanvas", srcImage[1]);
}

function loadImg(url) {
    return new Promise((resolve, reject) => {
        let img = new Image();
        // img.crossOrigin = 'anonymous';
        // 跨域 直接用live server运行
        img.src = url;
        img.onload = () => {
            resolve(img);
        };
        img.onerror = reject;
    });
}

/**
 * @function
 * @description !!!未完成python numpy.hstack函数实现
 * @param {[cv.Mat, cv.Mat]} rep 
 * @return {cv.Mat}
 * @link opencv同时显示两张图片 https://blog.csdn.net/qq_34057614/article/details/124035027
 * @link python hstack源码功能实现 https://blog.csdn.net/W_weiying/article/details/89505153
 * 
 * @todo 完成该函数
*/
function p_numpy_hstack(rep) {
    // shape[0] height
    // shape[1] width
    // if (rep[0].shape.length > 1 && rep[1].shape.length > 1) {
    // if (rep[0].height !== undefined && rep[0].width !== undefined) {
    if (rep[0].rows !== undefined && rep[0].cols !== undefined && rep[1].rows !== undefined && rep[1].cols !== undefined) {
        let blank = [];
        for (let i = 0; i < rep[0].rows; i++) {
            blank = blank.concat(rep[0][i].concat(rep[1][i]))
        }
        return blank;
    } else {
        return rep[0].concat(rep[1]);
    }

}

/**
 * @function
 * @description python range函数实现
 * @param {number[]} out 结果
 * 
 * @param {number} start 起始（包含）
 * @param {number} stop  终止（不包含）
 * @param {number} [step = 1] 步长, 默认1
 * @return {void}
 * 
 * @todo 通过arguments实现的函数重载代码注释
 * 
*/
// function p_range(out, start, stop, step = 1) {
function p_range() {
    let out = null;
    let start = 0;
    let stop = 0;
    let step = 1;
    if (arguments.length < 2) {
        return;
    } else if (arguments.length == 2) {
        out = arguments[0];
        start = 0;
        stop = arguments[1];
        step = 1;
    } else if (arguments.length == 3) {
        out = arguments[0];
        start = arguments[1];
        stop = arguments[2];
        step = 1;
    } else if (arguments.length == 4) {
        out = arguments[0];
        start = arguments[1];
        stop = arguments[2];
        step = arguments[3];
    } else {
        return;
    }
    for (let i = start; i < stop; i += step) {
        out.push(i);
    }
}